package cc.wanforme.fsync.entity;

import cc.wanforme.fsync.entity.po.ClientNode;
import org.springframework.beans.BeanUtils;

/** 同步单个文件的信息 */
public class SyncMeta {
    // group 的 name
    private String name;

    // server 的文件
    //private ClientNode serverNode;

    // client 的文件
    private ClientNode clientNode;


    /* server 的文件，<br/>
     * SyncMetaDto 中相对 sourceBase 的路径， sourceBase为 null 时，表示全路径
     */
    private String source;

    /* client 的文件。<br>
     * SyncMetaDto 中 相对 targetBase 的路径， targetBase null 时，表示全路径。
     * 递归同步文件夹时才会用到。用于处理 rewritePath 重写文件路径。
     * */
    private String target;

    /* 同步文件的场景中才会用的字段。<br>
     * 每次创建新文件夹，当此项存在时， cover 无意义。但不排除文件夹已存在的情况。<br>
     * 规则，默认 null，表示不重写。 必须以 ':' 开头， ':' 表示上面 'targetBase' 路径，
     * */
    private String rewritePath;

    // client 存在文件时，覆盖文件
    private boolean cover;

    /* 默认 true
     * 当文件未发生变化时，忽略此文件。 <br>
     * 比较方式是， server 和 client 的文件进行比较，即 source 和 target 进行比较。
     * 变化判断：文件修改时间发生变化。
     */
    private boolean ignoreUnchanged = true;

    // 仅存在于 client 上的文件。 0 - 不处理， 1 - 删除
    private int fileOnlyOnClient = 0;

    public SyncMeta() {}

    public static SyncMeta from(SyncMeta source) {
        SyncMeta meta = new SyncMeta();
        BeanUtils.copyProperties(source, meta);
        return meta;
    }

    /** 获取经过 rewritePath 转换后的文件真实路径。<br/>
     * 仅适用于文件，不适用文件夹
    public String decodeRewritePath() {
        if(rewritePath == null) {
            return target;
        }

        File file = new File(target);
        String fileName = file.getName();
        String parent = file.getParent();

        String nameNoSuffix = FileNameUtil.getNameNoSuffix(fileName);
        String suffix = FileNameUtil.getSuffix(fileName);

        // 先替换时间
        StringBuffer sb = new StringBuffer();
        Matcher matcher = rewritePattern.matcher(rewritePath.trim());
        LocalDateTime now = LocalDateTime.now();
        while(matcher.find()) {
            String str = matcher.group();
            if(str.equals("")){
                continue;
            }

//            System.out.println("str: " + str);
            String patternStr = str.substring(1, str.length()-1);
            DateTimeFormatter formatter = DateTimeTool.getFormatter(patternStr);
            if(formatter != null) {
                String time = formatter.format(now);
                matcher.appendReplacement(sb, time);
            } else {
                matcher.appendReplacement(sb, str);
            }
        }
        matcher.appendTail(sb);

        // 再替换父路径和无后缀文件名
        String finalStr = sb.isEmpty() ? rewritePath : sb.toString();
        finalStr = parent + finalStr.substring(1) // finalStr.replace(":", parent)
                .replace("?", nameNoSuffix)
            + suffix;
        return finalStr;
    }
     */

    public void setName(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public ClientNode getClientNode() {
        return clientNode;
    }

    public void setClientNode(ClientNode clientNode) {
        this.clientNode = clientNode;
    }

    public String getSource() {
        return source;
    }

    public void setSource(String source) {
        this.source = source;
    }

    public String getTarget() {
        return target;
    }

    public void setTarget(String target) {
        this.target = target;
    }

    public boolean isCover() {
        return cover;
    }

    public void setCover(boolean cover) {
        this.cover = cover;
    }

    public String getRewritePath() {
        return rewritePath;
    }

    public void setRewritePath(String rewritePath) {
        this.rewritePath = rewritePath;
    }

    public boolean isIgnoreUnchanged() {
        return ignoreUnchanged;
    }

    public void setIgnoreUnchanged(boolean ignoreUnchanged) {
        this.ignoreUnchanged = ignoreUnchanged;
    }

    public void setFileOnlyOnClient(int fileOnlyOnClient) {
        this.fileOnlyOnClient = fileOnlyOnClient;
    }

    public int getFileOnlyOnClient() {
        return fileOnlyOnClient;
    }

}
